home *** CD-ROM | disk | FTP | other *** search
Text File | 1989-06-12 | 51.6 KB | 1,836 lines |
- .title k11rms rms i/o for KERMIT-11
- .ident /3.56.0/
- .library /LB:[1,1]RMSMAC.MLB/
-
-
- ; Brian Nelson 30-Nov-83 09:53:49
- ;
- ; Copyright (C) 1983 Change Software, Inc.
- ;
- ; Edited by:
- ; RBD01 - Bob Denny 03-Mar-84 See K11CMD for edit trails
- ;
- ;
- ; *******************************************************
- ; * NOTES REGARDING DECnet (DAP) REMOTE FILE SUPPORT) *
- ; *******************************************************
- ;
- ; The code here contains some magic for DECnet (DAP) remote file
- ; access. I have not been able to find documentation on the DAP
- ; support that is present in RMS-11 (V2). My current understanding
- ; of this, through experimentation, is as follows:
- ;
- ; 1. $PARSE fails with RMS status ER$UIN when given a file
- ; specification containing a node name, but seems to
- ; merge the input string and defaults into the expanded
- ; string buffer anyway. It also sets the file specification
- ; mask. I have assumed that the ER$UIN error is encountered
- ; in $PARSE after the merging of the default and input
- ; filespec information, and reflects the "fact" that RMS-11
- ; (V2) DOES NOT SUPPORT WILDCARDING ON REMOTE FILE ACCESS.
- ;
- ; 2. Therefore, lookup() has been modified to return the
- ; expanded string if its second calling parameter (index)
- ; is zero (1st call) and there is either a node name or a
- ; quoted literal in the spec, no wildcards and the error
- ; is ER$UIN.
- ;
- ; 3. fparse() has been modified to accept if the error is ER$UIN,
- ; and if there are no wildcards and there is a node name present.
- ; The FB$FID bit is cleared, however, so that the original
- ; file spec string and the defaults will be used by $OPEN.
- ;
- ; 4. The "SY:" defaulting is not necessary, and in fact causes
- ; remote accesses to fail on VMS systems, where "SY:" has
- ; no conventional meaning.
- ;
- ; 5. The other routines which use $parse have been similarly
- ; modified to use the expanded string once only.
- ;
- ; 6. Finally, the NAMCVT routine in K11M41 was changed to handle
- ; quoted sections in strings and node names. This was the
- ; hardest part of the DAP adaptation.
- ;
- ; I have to believe that $parse and friends act this way because remote
- ; wildcarding got "left out" at the last minute because of scheduling
- ; problems in the RMS group. The code I have added here should permit
- ; remote wildcarding when it is turned on by the RMS folks.
- ;
- ; Bob Denny 03-Mar-84
- ;
- ;
- ;
- ; Please note that RSTS rms11 requires a real default device. I thus
- ; have to put my origional default for SY: back in for RSTS only. We
- ; will determine this at tkb time by defining a global called FU$DEF
- ; to be <> 0 in K11E80.MAC and = 0 in K11M41.MAC.
- ;
- ;
- ; Brian Nelson 16-Mar-84 17:34:19
- ;
- ; BDN 17-Feb-87 08:57:48 Re-do the allocation of record buffers so
- ; can GBLDEF the size during TKB. This will
- ; allow the I/D space Kermit to handle much
- ; larger ascii records.
-
-
- ; define macros and things we want for KERMIT-11
-
- .if ndf, k11inc
- .ift
-
-
- .if ndf, K11INC
- .ift
- .include /IN:K11MAC.MAC/
- .endc
-
- .endc
- .iif ndf, k11inc, .error ; INCLUDE for IN:K11MAC.MAC failed
-
-
- ; This is K11RMS.MAC, the RMS11 version 2 i/o interface for
- ; Kermit on RSTS version 8, RSX11M+ v2.1 and RSX11M v4.1. It
- ; is, without a doubt, the worst part of Kermit due RMS11,
- ; but it's strong points are future uses and the RSX / RSTS
- ; transportability. An example of "future uses" is DECnet
- ; remote file access (DAP) support now present.
- ;
- ;
- ; open ( %loc filename, %val channel_number ,%val type )
- ; create( %loc filename, %val channel_number ,%val type )
- ; getrec( %loc buffer , %val channel_number ) { returns RSZ in R1}
- ; putrec( %loc buffer , %val record_size ,%val channel_number )
- ; close ( %val channel_number )
- ; putc ( %val char , %val channel_number )
- ; getc ( %val channel_number )
-
-
- cr = 15
- lf = 12
- ff = 14
- soh = 1
- ;
- ; This isn't defined globally. (??)
- ;
- nb$nod = 400 ; Node in file or default string (FNB in NAM)
-
- .enabl gbl
-
- .psect $code ,ro,i,lcl,rel,con
- .psect rmssup ,rw,d,lcl,rel,con
-
-
- .mcall fabof$
- .mcall rabof$
- .mcall xabof$
- .mcall ifaof$
-
- fabof$ RMS$L
- rabof$ RMS$L
- xabof$ RMS$L
- ifaof$ RMS$L
-
-
- .mcall fab$b ,fab$e ,rab$b ,rab$e
- .mcall xab$b ,xab$e
- .mcall nam$b ,nam$e
- .mcall $initif ,org$
- .mcall pool$b ,pool$e ,p$bdb ,p$fab
- .mcall p$rabx ,p$idx ,p$buf
-
- .mcall $compar ,$fetch ,$store ,$rewin
- .mcall $close ,$creat ,$erase ,$open
- .mcall $connec ,$delet ,$discon,$find
- .mcall $get ,$put ,$updat ,$flush
- .mcall $read ,$write ,$off ,$set
- .mcall $testbits
-
-
- org$ SEQ,<CRE,DEL,GET,PUT>
-
- .psect rmssup ,rw,d,lcl,rel,con ; ORG$ macro needs .save/.restore
-
-
- .if ne ,0 ; Decide whether or not to use
- .ift ; dynamic space allocation by
- ; task extension or to use
- rmsbuf: pool$b ; static pools
- p$rab 6 ; plenty of record streams
- p$bdb 6 ; same goes for block buffers
- p$fab 4 ; up to 3 fabs (needed for search)
- p$buf 3072. ; for 2 files and directory i/o
- pool$e ; end of static pool
-
- .iff ; use task extension for space
- ; routine modifed from GSA example
- .mcall gsa$ ; from RMS v2.0 distribution.
- gsa$ gsa ; set our GSA address
- .globl gsa ; it may be global
-
- .endc ; to decide on pool allocation
-
- .psect rmssup ,rw,d,lcl,rel,con ; GSA$ macro needs .save/.restore
-
-
-
- .sbttl rms file access blocks
-
- facc = fb$get ! fb$put
-
- fab1: fab$b
- f$alq 0 ; initial allocation of 10 blocks
- f$fac facc ; allowed i/o operations
- f$fna nam1 ; name of the file
- f$fns 0 ; length of the filename
- f$fop fb$sup ; supercede old versions
- f$lch lun1 ; channel number to use
- f$org fb$seq ; seq
- f$rat fb$cr ; implied carriage control
- f$rfm fb$var ; variable length records
- f$xab datxb1 ; Date info
- fab$e
- fab1en:
-
- fab2: fab$b
- f$alq 0 ; initial allocation of 10 blocks
- f$fac facc ; allowed i/o operations
- f$fna nam2 ; name of the file
- f$fns 0 ; length of the filename
- f$fop fb$sup ; supercede old versions
- f$lch lun2 ; channel number to use
- f$org fb$seq ; seq
- f$rat fb$cr ; implied carriage control
- f$rfm fb$var ; variable length records
- f$xab datxb2 ; Date info
- fab$e
- fab2en:
-
-
- fab3: fab$b
- f$alq 0 ; initial allocation of 10 blocks
- f$fac facc ; allowed i/o operations
- f$fna nam3 ; name of the file
- f$fns 0 ; length of the filename
- f$fop fb$sup ; supercede old versions
- f$lch lun3 ; channel number to use
- f$org fb$seq ; seq
- f$rat fb$cr ; implied carriage control
- f$rfm fb$var ; variable length records
- f$xab datxb3 ; Date info
- fab$e
- fab3en:
-
-
- fab4: fab$b
- f$alq 0 ; initial allocation of 10 blocks
- f$fac facc ; allowed i/o operations
- f$fna nam4 ; name of the file
- f$fns 0 ; length of the filename
- f$fop fb$sup ; supercede old versions
- f$lch lun4 ; channel number to use
- f$org fb$seq ; seq
- f$rat fb$cr ; implied carriage control
- f$rfm fb$var ; variable length records
- f$xab datxb4 ; Date info
- fab$e
-
- GLOBAL <MAXSIZ>
-
-
- .psect rmssup ,rw,d,lcl,rel,con
-
- sydisk::.ascii /SY:/
- sylen == . - sydisk
- .even
- sydska == sydisk
- sydskl == sylen
-
- ; ;RBD01--
- ; pointers to buffer and fabs
- ;
- ; While none of this is really needed since all this info is
- ; available in the FAB and RAB, I find it cleaner to do it
- ; this way and thus avoid having to look at the RMS control
- ; structures.
-
- fablst::.word 0 ,fab1 ,fab2 ,fab3 ,fab4
- namlst::.word 0 ,nam1 ,nam2 ,nam3 ,nam4
- namlen::.word 0 ,0 ,0 ,0 ,0
- rablst::.word 0 ,rab1 ,rab2 ,rab3 ,rab4
- buflst: .word ttbuf ,buf1 ,buf2 ,buf3 ,buf4
- bufdef: .word ttbuf ,buf1 ,buf2 ,buf3 ,buf4
- bufsiz: .word TTBSIZ ,MAXSIZ ,MAXSIZ ,MAXSIZ ,MAXSIZ
- bigbuf: .word bufx ,bufx ,bufx ,bufx ,bufx
- filtyp: .word TERMINAL,TEXT ,TEXT ,TEXT ,TEXT
- bufp: .word 0 ,0 ,0 ,0 ,0
- bufs: .word 0 ,0 ,0 ,0 ,0
- mode: .word 1 ,0 ,0 ,0 ,0
- blknum: .word 0 ,0 ,0 ,0 ,0
- itsopen:.word 0 ,0 ,0 ,0 ,0
-
- FILSIZ == 110.
- BINLSIZ == 30*4
-
- defdir::.blkb FILSIZ+2 ; default directory for send and rec
- srcnam::.blkb FILSIZ+2 ; original send filespec
- filnam::.blkb FILSIZ+2 ; output from directory lookup routine
- asname::.blkb FILSIZ+2 ; for SEND file [as] file
- $cmdbu::.blkb 120
- $argbu::.blkb 120
- bintyp::.word 10$
- 10$: .rept BINLSIZE
- .byte 0
- .endr
- totp.r::.word 10$
- 10$: .rept 34
- .word 0,0
- .endr
- totp.s::.word 10$
- 10$: .rept 34
- .word 0,0
- .endr
-
- ; this sets the default for creating text files
-
- df$rat::.word fb$cr
- df$rfm::.word fb$var
- en$siz::.word 0 ; for RT11 compatibilty
-
- namln1 = namlen+2
- namln2 = namlen+4
- namln3 = namlen+6
- namln4 = namlen+10
-
- nam1: .rept 100
- .byte 0
- .endr
-
- nam2: .rept 100
- .byte 0
- .endr
-
- nam3: .rept 100
- .byte 0
- .endr
-
- nam4: .rept 100
- .byte 0
- .endr
- .even
-
-
- packet::.blkb MAXLNG+100 ; /51/ Moved.
- .even
-
- top: .LIMIT
-
- TTBSIZ = 40
- ttbuf: .blkb TTBSIZ+2
-
- buf1: .iif df, MAXSIZ, .blkb MAXSIZ+2 ; /56/ Dynamic or static setup?
- buf2: .iif df, MAXSIZ, .blkb MAXSIZ+2 ; /56/ ...
- buf3: .iif df, MAXSIZ, .blkb MAXSIZ+2 ; /56/ ....
- buf4: .iif df, MAXSIZ, .blkb MAXSIZ+2 ; /56/ .....
-
- bufx: .blkb 1002 ; one large buffer to share
-
-
- lun1 = 1
- lun2 = 2
- lun3 = 3
- lun4 = 4
- maxlun = lun4
-
-
-
- .sbttl rms record access blocks
-
- rab1: rab$b ; define record access block
- r$fab fab1 ; associate a fab with this rab
- r$rac rb$seq ; access by keys
- r$rbf buf1 ; where to return the data
- r$ubf buf1 ; where to return the data
- rab$e ; end of record access block
-
- rab2: rab$b ; define record access block
- r$fab fab2 ; associate a fab with this rab
- r$rac rb$seq ; access by keys
- r$rbf buf2 ; where to return the data
- r$ubf buf2 ; where to return the data
- rab$e ; end of record access block
-
- rab3: rab$b ; define record access block
- r$fab fab3 ; associate a fab with this rab
- r$rac rb$seq ; access by keys
- r$rbf buf3 ; where to return the data
- r$ubf buf3 ; where to return the data
- rab$e ; end of record access block
-
- rab4: rab$b ; define record access block
- r$fab fab4 ; associate a fab with this rab
- r$rac rb$seq ; access by keys
- r$rbf buf4 ; where to return the data
- r$ubf buf4 ; where to return the data
- rab$e ; end of record access block
-
-
-
- proxab: xab$b XB$PRO ; file protection xab
- x$nxt 0 ; no more links
- x$pro 60. ; normal protection of <60>
- xab$e ; end of file protection xab
-
- datxb1: xab$b XB$DAT
- x$nxt 0
- xab$e
- datxb2: xab$b XB$DAT
- x$nxt 0
- xab$e
- datxb3: xab$b XB$DAT
- x$nxt 0
- xab$e
- datxb4: xab$b XB$DAT
- x$nxt 0
- xab$e
-
- .psect $code
-
-
- .sbttl Set up SST table to catch RMSRES missing
-
- .mcall SVTK$S,EXST$S,EXTK$S ; This code added /53/
- .mcall GTSK$S
-
- ; Dynamic record buffer allocation and dynamic recall buffer
- ; allocation added /56/
-
-
- .save ; Save current PSECT
- .psect RMSSUP ,D ; Switch to a data psect
- .even ; Insure this
- tbl: .word 0,0,norms ; Missing RMS gives a BPT trap
- nolib: .byte CR,LF
- .ascii /Probable cause: Either RMSRES or an RMS satellite/<CR><LF>
- .asciz /resident library is not installed on this system./<CR><LF>
- .even
- .restore ; Pop old psect
- .enabl lsb
-
-
- Rmsini::mov #MAXSIZ ,r3 ; Allocate record buffers
- mov r3 ,O$MRS+fab1 ; Since we are allocating
- mov r3 ,O$MRS+fab2 ; the RMS record buffers at
- mov r3 ,O$MRS+fab3 ; run time we will can't
- mov r3 ,O$MRS+fab4 ; fill these fields in with
- mov r3 ,O$USZ+rab1 ; ...MAC
- mov r3 ,O$USZ+rab2 ; .... and so on
- mov r3 ,O$USZ+rab3 ; ....
- mov r3 ,O$USZ+rab4 ; ....
- ;
- .If df ,MAXSIZ ; Dynamic or static today?
- .Ift ; Static
- ;
- mov #buf1 ,r2 ; So get the preallocated buffers
- mov top+2 ,r4 ;
- .Iff ; Dynamic allocation
- ;
- ash #-<6-2> ,r3 ; We need 4 buffers, in 64 byte
- add #2 ,r3 ; chuncks. Add a safety margin
- EXTK$S r3 ; Ask for the memory
- bcs 110$ ; Oops, we will have to die.
- mov top+2 ,r2 ; The higest virtual address+2
- add #2 ,r2 ; filled in by TKB via .LIMIT
- bic #1 ,r2 ; Insure even
- ;
- .Endc ; .If DF, Maxsiz
- ;
- mov #4 ,r0 ; Number of fields to update
- clr r3 ; Offset into BUFDEF and BUFLST
- 10$: mov r2 ,bufdef+2(r3) ; Insert a record buffer address
- mov r2 ,buflst+2(r3) ; Ditto for here also
- add #2 ,r3 ; Next please
- add #MAXSIZ+2,r2 ; Point to the next buffer
- sob r0 ,10$ ; And go do another
- .If ndf ,MAXSIZ ; Setup pointer for command line
- mov r2 ,r4 ; recall buffers if dynamic RMS
- .Endc ; buffer allocation was used
- ; Now for command line recall
- mov #LNCNT$ ,r1 ; buffers. The count is defined
- cmp r1 ,#LN$ALL ; via a GBLDEF=LNCNT$:n by TKB.
- bgt 120$ ; Ensure enough vector space. No, die
- mov #<LN$MAX+2>*LNCNT$,r3 ; Total byte count for recall buffers
- ash #-6 ,r3 ; In 64 byte chunks
- add #<LN$MAX+2>/100,r3 ; Fix for truncation
- EXTK$S r3 ; Ask for it
- bcs 130$ ; No room, die (should never happen)
- mov r1 ,lastcnt ; Save the number of recall buffers
- mov #lastli ,r2 ; The pointer array
- 40$: mov r4 ,(r2)+ ; Insert the buffer address
- clrb @r4 ; Insure the buffer is zapped
- add #LN$MAX+2,r4 ; Get to the next one
- sob r1 ,40$ ; And loop
- ;
- ; Finally, our original purpose.
- SVTK$S #tbl,#3 ; Only want TBIT traps
- return ; Exit
-
-
- 110$: Message <Failure to allocate record buffers>,CR
- br 200$
- 120$: Message <LN$ALL is less than LNCNT$>,CR
- br 200$
- 130$: Message <Failure to allocate command recall buffers>,CR
-
- 200$: EXST$S #EX$SEV ; Die...
-
- .dsabl lsb
-
-
-
- Norms: MESSAGE <Breakpoint trap, > ; A message
- mov (sp) ,r1 ; Dump PC and PS
- MESSAGE < PC: > ; A header
- OCTOUT R1 ; ...
- mov 2(sp) ,r1 ; PS
- MESSAGE < PSW: > ; ...
- OCTOUT r1 ; ...
- cmp (sp) ,#140000 ; Perhaps RMSRES missing?
- blo 100$ ; No
- PRINT #nolib ; Dump the cause
- 100$: EXST$S #EX$SEV ; Die
-
- Global <LNCNT$>
-
-
-
-
- .sbttl create sequential file
- .psect $code
- .even
-
- ; F C R E A T E and FOPEN
- ;
- ; fcreate( %loc filename; %val channel_number, %val type ,%val mb_count)
- ; fopen ( %loc filename; %val channel_number, %val type ,%val mb_count)
- ;
- ; input: @r5 filename address
- ; 2(r5) channel number
- ; 4(r5) val 'binary' or 'text' or 0
- ; 6(r5) RMS multiblock count for the stream
- ;
- ; output: r0 rms error code
- ;
- ; Create a variable length sequential implied carriage control
- ; disk file. If 'type' is 'binary' then use read/write access
- ; to write a fixed 512 byte image file. If channel number is
- ; zero (0), then initialize buffer single character terminal
- ; output. It is always assumed that channel '0' implies writes
- ; to the attached console terminal.
-
- .enabl lsb
- open:: calls fopen ,<@r5,2(r5),4(r5),#0>
- return
-
- create::calls fcreate ,<@r5,2(r5),4(r5),#0>
- return
-
- append::calls fapnd ,<@r5,2(r5),4(r5),#0>
- return
-
-
- fopen:: save <r1,r2,r3> ; save registers
- call drpprv ; insure no privs are up now +MJG
- clr -(sp) ; flag for open not create
- br 5$ ; and try to do it
-
-
- fapnd:: save <r1,r2,r3> ; save registers +SSH
- call drpprv ; insure no privs +SSH
- mov #1,-(sp) ; flag for open / append +SSH
- br 5$ ; and try to do it +SSH
-
-
- fcreat::save <r1,r2,r3> ; save registers
- call drpprv ; insure no privs are up now +MJG
- tcreat: mov #-1 ,-(sp) ; flag for create
-
- 5$: $initif ; initialize rms i/o system if needed
- mov 2(r5) ,r0 ; get channel number please
- bne 10$ ; not channel zero, do it normally
-
- mov sp ,itsopen+0 ; flag it as having been initted
- mov sp ,mode+0 ; psuedo writing to the terminal
- clr bufp+0 ; initialize the terminal's buffer
- br 120$ ; pointer and exit
-
- 10$: asl r0 ; times 2
- mov r0 ,r2 ; save it please
- mov namlst(r2),r1 ; get address of name block
- calls fparse ,<@r5,r1> ; parse and fill in defaults
- tst r0 ; did the parse succeed ?
- bne 120$ ; no, exit with RMS error in r0
- strlen r1 ; get the expanded filename length
- mov r0 ,namlen(r2) ; and save the length
- mov r2 ,r0 ; get r0 back again please
- mov fablst(r0),r1 ; get the file access block
- mov @sp ,r2 ; pass create/open/append flag /SSH
- call settyp ; setup the FAB now
- mov r0 ,r2 ; save the channel number*2
- tst @sp ; create or open or append /SSH
- bmi 30$ ; if negative then create /SSH
-
- $open r1 ; try to open existing file /SSH
- tst @sp ; opening for append ? +SSH
- beq 28$ ; no, go setup for read +SSH
- mov sp ,mode(r2) ; indicate open for writing +SSH
- clr bufp(r2) ; clear single char i/o pointer +SSH
- br 40$ ; continue with status check +SSH
- 28$: ; +SSH
- mov #-1 ,bufp(r2) ; init for buffer needing a read
- clr mode(r2) ; no writing please
- br 40$ ; check RMS status out now
-
- 30$: $creat r1 ; try hard to create the file
- mov sp ,mode(r2) ; open for writing
- clr bufp(r2) ; clear single character i/o pointer
-
- 40$: $fetch r0,sts,r1 ; get status back out please
- tst r0 ; if status > 0 then status = 0
- bmi 130$ ; error if less than zero /SSH
- mov 2(r5) ,r0 ; connect access up now
- asl r0 ; flag also that we are open
- mov sp ,itsopen(r0) ; simple
- asr r0 ; restore r0 now
- mov 6(r5) ,r1 ; and the multiblock count also
- mov (sp) ,r2 ; and the create/open/append opt +SSH
- call rmscon ; connect record stream up
- tst r0 ; if error > 0 then error = 0
- bmi 120$ ; yep
- clr r0 ; error = 0
-
- 120$: tst (sp)+ ; pop open/create flag
- 125$: unsave <r3,r2,r1> ; pop registers we saved
- return ; and exit
-
- 130$: tst (sp)+ ; if error on open for append +SSH
- ble 125$ ; no, return with error +SSH
- br tcreat ; yes, try creating the file +SSH
-
- global <drpprv> ; +MJG
-
- .dsabl lsb
-
- .sbttl setup things for open/create in the FAB
-
-
- ; S E T T Y P
- ;
- ; input: r0 channel number times 2
- ; r2 <> 0 implies create
- ; r5 --> open/create parameter list
- ;
- fbrw = fb$rea ! fb$wri
-
- settyp::mov fablst(r0),r1
- clr blknum(r0) ; in case of read/write mode
- mov #MAXSIZ ,bufsiz(r0) ; default for the buffer size
- mov #text ,filtyp(r0) ; assume ascii text files for now
- mov bufdef(r0),buflst(r0) ; set a default record buffer also
- clr bufs(r0) ; clear single character i/o recsiz
- $store #proxab,XAB,r1 ; /59/ Get the protection out.
- $store namlen(r0),FNS,r1
- $store #fb$seq,ORG,r1 ; insure sequential by default
- $store df$rat ,RAT,r1 ; implied carriage control
- $store df$rfm ,RFM,r1 ; and also variable length records
- $store #fb$get,FAC,r1 ; insure readonly please
- tst fu$def ; do we require a default device
- beq 1$ ; no
- $store #sydisk,DNA,r1 ; yes, stuff the correct def dev in
- $store #sylen ,DNS,r1 ; and the length of it also please
- 1$: tst r2 ; if creating or appending the file /SSH
- beq 10$ ; no /SSH
- $store #<fb$put>,FAC,r1 ; yes, get put access /SSH
- mov at$pr0 ,proxab+O$PRO ; /59/ Protection explicity set?
- bne 10$ ; /59/ Yes
- $store #0,XAB,r1 ; /59/ No, remove the protection XAB
- 10$: cmp 4(r5) ,#binary ; is this a binary file ?
- bne 100$ ; no, just exit
-
- mov #1000 ,bufsiz(r0) ; yes, fix it up for that
- mov bigbuf(r0),buflst(r0) ; setup a large i/o buffer please
- mov #binary ,filtyp(r0) ; please
- $store #0 ,RAT,r1 ; no cr/lf implied please
- $store #fb$fix ,RFM,r1 ; fixed length also
- $store #fb$rea ,FAC,r1 ; assume read only please
- tst r2 ; readonly ?
- beq 30$ ; yes
- $store #fbrw ,FAC,r1 ; read/write mode needed ?
- 30$: save <r2,r3> ; zero out the big buffer
- mov buflst(r0),r2 ; get the buffer address
- mov #1000 ,r3 ; 1000 (8) bytes please
- 40$: clrb (r2)+ ; simple
- sob r3 ,40$ ; next please
- unsave <r3,r2> ; pop registers we just used
-
- 100$: $store bufsiz(r0),MRS,r1 ; stuff max recordsize in please
- return
-
- global <fu$def>
- GLOBAL <AT$PR0> ; /59/ Protection mask
-
-
-
- .sbttl close a file
-
-
- close:: save <r1,r2,r3> ; save registers we may have
- mov @r5 ,r0 ; get the lun
- asl r0 ; times 2
- tst itsopen(r0) ; check for lun being open
- beq 90$ ; no, skip all this then
- clr itsopen(r0) ; not anymore please
- call flush ; dump out any remaining buffer
- mov @r5 ,r0 ; then disconnect the access stream
- beq 100$ ; terminal
-
- asl r0 ; channel number times 2
- tst mode(r0) ; writing to it today?
- beq 10$ ; no
- calls atrfin ,<@r5> ; yes, perhaps do attribute things
- 10$: mov @r5 ,r0 ; then disconnect the access stream
- call rmsdis ; by doing a $disconnect
- mov @r5 ,r1 ; get the FAB for the file open on
- asl r1 ; the passed channel
- mov fablst(r1),r1 ;
- $close r1 ; try hard to close the file
- $fetch r0,sts,r1 ; get status back out please
- tst r0 ; if status > 0 then status = 0
- blt 100$ ; error if less than zero
- 90$: clr r0 ; make > 0 status eq 0
- 100$: unsave <r3,r2,r1>
- return
-
-
- rewind::mov @r5 ,r0
- beq 100$
- asl r0
- mov rablst(r0),r0
- $rewind r0
- 100$: clr r0
- return
-
-
-
- .sbttl try to determine if a file needs binary xfer mode
-
- ; B I N F I L
- ;
- ; input: @r5 address of the filename
- ; 2(r5) lun
- ; output: r0 < 0 then RMS error
- ; r0 > 0 then the file is most likely binary
-
-
- binfil::save <r1,r2,r3,r4> ; save registers we may use
- clr r4 ; nothing is open as of yet
- calls chkext ,<@r5> ; check file based on filetype
- tst r0 ; assume a binary file ?
- bne 100$ ; yep
- mov 2(r5) ,r2 ; get the lun
- asl r2 ; times 2
- mov fablst(r2),r2 ; get the fab address now
- $fetch r3,XAB,r2 ; save the xab link address
- call getuic ; for RSTS, skip the protection XAB
- swab r0 ; if the user is not privledged
- cmpb r0 ,#1 ; since RMS uses the UU.LOK directive
- bne 5$ ; which may be patched to fail.
- $store #proxab,XAB,r2 ; and stuff our own into it
- 5$: calls open ,<@r5,2(r5),#binary>
- tst r0 ; did the open work
- bmi 90$ ; no
- mov sp ,r4 ; flag that it's open
-
- call getsys ; if this is RSTS then a protection
- cmpb r0 ,#sy$rsts ; bit of 100 being set indicates an
- bne 10$ ; executable file
- mov #proxab ,r1 ; get the xab for the protection code
- $testbit #100,PRO,r1 ; if set, then it's executable
- bne 40$ ; assume it's binary
-
- 10$: $testbit #<fb$rel!fb$idx>,ORG,r2; indexed or relative file ?
- bne 40$ ; yes, it must be sent as a binary file
- $compare #fb$stm,RFM,r2 ; stream ascii file ?
- beq 30$ ; yes, assume not binary then
- $testbit #FB$FTN,RAT,r2 ; /47/ Please not for Fortran files
- bne 30$ ; /47/ Ok
- $testbit #fb$cr,RAT,r2 ; implied carriage control ?
- bne 30$ ; yes, assume not 8 bit then
- br 40$ ; anything else is binary please
-
-
- 30$: clr -(sp) ; flag as most likely being ascii
- br 50$ ; bye
- 40$: mov #1 ,-(sp) ; flag as being binary and exit
- 50$: tst r4 ; ever opened up ?
- beq 60$ ; no
- calls close ,<2(r5)> ; close up
- 60$: mov (sp)+ ,r0
- 90$: $store r3,XAB,r2 ; restore old xab links, if any
-
- 100$: unsave <r4,r3,r2,r1> ; bye
- return
-
-
- .sbttl getatr return attributes for a file already open
-
- .mcall ifaof$ ; access the ifab for the fab
- ifaof$ rms$l ; get the ifab symbols defined
-
-
- getsiz::mov @r5 ,r1 ; return error in r0, size in r1
- asl r1 ; lun times 2
- mov fablst(r1),r1 ; fab for this file
- mov <o$alq+0>(r1),r1 ; get the size please
- clr r0 ; no errors
- return ; exit
-
- getpro::mov @r5 ,r0 ; size in r0
- asl r0 ; lun times 2
- mov fablst(r0),r0 ; fab for this file
- mov O$XAB(r0),r0 ; get the protection please
- mov O$PRO(r0),r0 ; ...
- return ; exit
-
-
-
- ; Getcdt Return time/date of creation, system (ie, RMS vs RT) dep.
- ;
- ; Passed: 2(r5) Channel number file is open on
- ; Return: R0 Zero if failure (internal error) else address of
- ; 64 byte Smithsonian date format
-
-
- Getcdt::mov @r5 ,r0 ; Channel
- beq 100$ ; Oops
- asl r0 ; Word offsets
- mov FABLST(r0),r0 ; Get the fab
- beq 100$ ; Impossible
- mov O$XAB(r0),r0 ; XAB address
- beq 100$ ; Nothing
- add #O$CDT ,r0 ; Point to 4word creation dat/tim
- 100$: return ; Exit
-
- Putcdt::mov @r5 ,r0 ; Channel
- beq 100$ ; Oops
- asl r0 ; Word offsets
- mov FABLST(r0),r0 ; Get the fab
- beq 100$ ; Impossible
- mov O$XAB(r0),r0 ; XAB address
- beq 100$ ; Nothing
- add #O$CDT ,r0 ; Point to 4word creation dat/tim
- mov 2(r5) ,r1 ; Data
- mov (r1)+ ,(r0)+ ; Copy it
- mov (r1)+ ,(r0)+ ; .Copy it
- mov (r1)+ ,(r0)+ ; ..Copy it
- mov (r1)+ ,(r0)+ ; ...Copy it
- 100$: return ; Exit
-
-
- getatr::save <r1,r2> ; save these please
- mov @r5 ,r1 ; the channel number please
- asl r1 ; times two please
- mov fablst(r1),r1 ; simple
- mov o$ifi(r1),r1 ; and now we are at the ifab
- mov 2(r5) ,r2 ; where to copy the attributes to
- movb f$ratt(r1),(r2)+ ; stuff the input record attributes
- movb f$forg(r1),(r2)+ ; also stuff the input file org in
- mov f$rsiz(r1),(r2)+ ; and the input record size please
- mov f$hvbn(r1),(r2)+ ; and the input eof markers
- mov f$lvbn(r1),(r2)+ ; like hi and low virtual block
- mov f$heof(r1),(r2)+ ; and the high and low eof block
- mov f$leof(r1),(r2)+ ; numbers also
- mov f$ffby(r1),(r2)+ ; and, at last, the first free byte
- movb f$hdsz(r1),(r2)+ ; VFC header size next
- movb f$bksz(r1),(r2)+ ; and largest bucket size
- mov f$mrs(r1) ,(r2)+ ; the maximum record size
- mov f$deq(r1) ,(r2)+ ; and the default extenstion size
- mov f$rtde(r1),(r2)+ ; and the run time extentsion size
- 100$: unsave <r2,r1> ; all done
- clr r0 ; say it worked ok
- return
-
-
-
- putatr::save <r1,r2> ; save these please
- mov @r5 ,r1 ; the channel number please
- asl r1 ; times two please
- mov fablst(r1),r1 ; simple
- mov o$ifi(r1),r1 ; and now we are at the ifab
- mov 2(r5) ,r2 ; where to get the attributes from
- movb (r2)+ ,f$ratt(r1) ; stuff the input record attributes
- movb (r2)+ ,f$forg(r1) ; also stuff the input file org in
- mov (r2)+ ,f$rsiz(r1) ; and the input record size please
- mov (r2)+ ,f$hvbn(r1) ; and the input eof markers
- mov (r2)+ ,f$lvbn(r1) ; like hi and low virtual block
- mov (r2)+ ,f$heof(r1) ; and the high and low eof block
- mov (r2)+ ,f$leof(r1) ; numbers also
- mov (r2)+ ,f$ffby(r1) ; and, at last, the first free byte
- movb (r2)+ ,f$hdsz(r1) ; VFC header size next
- movb (r2)+ ,f$bksz(r1) ; and largest bucket size
- mov (r2)+ ,f$mrs(r1) ; the maximum record size
- mov (r2)+ ,f$deq(r1) ; and the default extenstion size
- mov (r2)+ ,f$rtde(r1) ; and the run time extentsion size
- 100$: unsave <r2,r1> ; all done
- clr r0 ; say it worked ok
- return
-
-
-
-
-
- .sbttl connect record access block to file access block
-
-
- ; C O N N E C T
- ;
- ; connect( %val channel_number )
- ;
- ; input: r0 channel number
- ; r1 multiblock count
- ; r2 create/open/append option flag +SSH
- ; output: r0 rms sts
- ;
- ; Connect a record access block to a file access block.
- ; Called only from OPEN and CREATE
-
-
- rmscon: mov r1 ,-(sp) ; the block count size
- mov r0 ,r1 ; get address of record access block
- asl r1 ; channel number times 2
- mov rablst(r1),r1 ; address of a rab to use
- $store (sp)+,MBC,r1 ; the block buffer count
- $store #0,ROP,r1 ; assume no processing options +SSH
- tst r2 ; if appending to existing file +SSH
- ble 7$ ; no, leave options alone +SSH
- $store #rb$eof,ROP,r1 ; yes, set position to EOF option +SSH
- 7$: ; +SSH
- $conne r1 ; try hard to connect access up
- $fetch r0,sts,r1 ; get status back out please
- tst r0 ; if status > 0 then status = 0
- blt 10$ ; error if less than zero
- clr r0 ; make > 0 status eq 0
- 10$: return
-
-
-
-
- .sbttl disconnect record access block from file access block
-
-
- ; R M S D I S
- ;
- ; input: r0 channel number
- ; r0 error sts
- ;
-
- rmsdis: mov r0 ,r1
- asl r1
- mov rablst(r1),r1
- $discon r1 ; disconnect access stream from file
- $fetch r0,sts,r1 ; get status back out please
- tst r0 ; if status > 0 then status = 0
- blt 10$ ; error if less than zero
- clr r0 ; make > 0 status eq 0
- 10$: return
-
-
-
- .sbttl read a record from a sequential file
-
-
- ; G E T R E C
- ;
- ; getrec( %loc buffer, %val channel_number )
- ;
- ; input: @r5 address of user buffer, at least 80 bytes
- ; 2(r5) channel number
- ;
- ; output: r0 rms sts
- ; r1 record size
- ;
- ; Read the next record from a disk file. Assumes that the
- ; user has supplied a buffer of 80 characters to return
- ; the record to.
-
-
- getrec::mov 2(r5) ,r0 ; get the channel number
- asl r0 ; times 2 to index into table
- mov rablst(r0),r1 ; get the record access buffer
- $store #0 ,RSZ,r1
- $store @r5 ,UBF,r1 ; stuff a record buffer in
- $store bufsiz(r0),USZ,r1 ; and a maximum record size
- cmp filtyp(r0),#binary ; a binary file today ?
- bne 10$ ; no, use normal get$
- clr o$bkt+0(r1) ; use sequential mode please
- clr o$bkt+2(r1) ; both words are to have zero
- $read r1 ; get next virtual block please
- br 20$ ; get error code out now
- 10$: $get r1 ; read a record now
- 20$: $fetch r0,STS,r1 ; get the return STATUS field
- tst r0 ; did it work ?
- blt 100$ ; no
- clr r0 ; say no errors
- $fetch r1,RSZ,r1 ; get the record size now
- 100$: return
-
- global <o$bkt>
-
-
- .sbttl put a record to an rms sequential file
-
-
- ; P U T R E C
- ;
- ; putrec( %loc buffer, %val record_size, %val channel_number )
- ;
- ; input: @r5 address of user buffer
- ; 2(r5) record size
- ; 4(r5) channel number
- ;
- ; output: r0 rms sts
- ;
- ; Write the next record to a disk file.
-
-
- putrec::mov r1 ,-(sp)
- mov 4(r5) ,r0 ; get the channel number
- bne 5$ ; if zero then assume TI:
- print @r5 ,2(r5) ; dump the buffer to ti: then
- br 100$ ; and exit
- 5$: asl r0 ; times 2 to index into table
- mov rablst(r0),r1 ; get the record access buffer
- $store @r5 ,RBF,r1 ; stuff a record buffer in
- $store 2(r5),RSZ,r1 ; and a current record size
- cmp filtyp(r0),#binary ; image mode today ?
- bne 10$ ; no
- $store #1000,RSZ,r1 ; yes, insure block write
- clr o$bkt+0(r1) ; yes, clear the VBN fields
- clr o$bkt+2(r1) ; yes, clear the VBN fields
- $write r1 ; simple
- br 20$ ; get the status and exit
- 10$: $put r1 ; write a record now /SSH
- 20$: $fetch r0,STS,r1 ; get the return STATUS field
- tst r0 ; did it work ?
- blt 99$ ; no
- clr r0 ; say no errors
- br 100$
- 99$: mov r0,tmperr ; store error code for debugging
- 100$: mov (sp)+ ,r1
- return
-
-
- .sbttl getc get one character from an input file
-
-
- ; G E T C
- ;
- ; getc(%val channel_number)
- ;
- ; input: @r5 channel_number
- ; output: r0 rms error status
- ; r1 the character just read
-
- getc:: mov @r5 ,r0
- call getcr0
- return
-
-
- fgetcr::save <r2,r3> ; save temps
- mov r0 ,r2 ; channel number please
- asl r2 ; times 2
- cmp bufp(r2),#-1 ; need to initialize the buffer?
- bne 10$ ; no
- calls getrec ,<buflst(r2),r0>; yes, load it please
- tst r0 ; did the read work ?
- bne 100$ ; no, return rms error code
- clr bufp(r2) ; it worked. clear current pointer
- mov r1 ,bufs(r2) ; and save the record size
- br 30$ ; and goto common code
-
- 10$: cmp bufp(r2),#-2 ; flag to return <cr> ?
- bne 20$ ; no
- movb #cr ,r1 ; yes, return it in r1
- mov #-3 ,bufp(r2) ; and setup for a <lf> nexttime
- clr r0 ; no error
- br 100$ ; bye
-
- 20$: cmp bufp(r2),#-3 ; flag to return a <lf> ?
- bne 30$ ; no
- movb #lf ,r1 ; yes, return <lf> in r1
- mov #-1 ,bufp(r2) ; flag buffer reload next time
- clr r0 ; no error
- br 100$
-
-
- 30$: tst bufs(r2) ; anything left to get in record?
- bne 40$ ; yes
- mov #-2 ,bufp(r2) ; no, flag for a <cr> next
- cmp filtyp(r2),#binary ; a binary file today ?
- bne 35$ ; yes, need data as is please
- mov #-1 ,bufp(r2) ; yes, flag for a read next
- 35$: mov r2 ,r0 ; channel number please
- asr r0 ; NOT times two
- call getcr0 ; call ourselves to do it
- br 100$ ; and exit
-
- 40$: mov buflst(r2),r3 ; get the address of the buffer
- add bufp(r2),r3 ; and point to the next character
- clr r1 ; to be returned in r1
- bisb @r3 ,r1 ; simple
- inc bufp(r2) ; buffer.pointer := succ(buffer.pointer)
- dec bufs(r2) ; amountleft := pred( amountleft )
- clr r0 ; no errors please
-
- 100$: unsave <r3,r2>
- return
-
-
-
- .sbttl putc put a single character to an rms file
-
- ; P U T C
- ;
- ; input: @r5 the character to put
- ; 2(r5) the channel number to use
- ;
- ; Buffer single character i/o to internal disk buffer.
- ; Buffer is dumped if internal buffer is full or, for
- ; FB$VAR records (default for TEXT), a carraige return
- ; is found. For FB$VAR with FB$CR format, all carraige
- ; returns and line feeds are flushed as this record
- ; format will have them put back later.
- ; The local buffers are allocated in CREATE and OPEN.
-
-
- putc:: save <r1> ; simply save r1 and call putcr0
- mov 2(r5) ,r1 ; to do it. putcr0 will be somewhat
- clr r0 ; faster to call directly due to the
- bisb @r5 ,r0 ; overhead involved in setting up an
- call putcr0 ; argument list.
- unsave <r1> ; pop saved r1 and exit
- return ; bye
-
-
- putcr0::save <r1,r2,r3,r4> ; save registers we use
- mov r1 ,r2 ; channel number
- asl r2 ; times 2 of course
- cmp filtyp(r2),#binary ; is this a binary file today ?
- beq 5$ ; yes, don't dump buffer on <cr>
- cmpb r0 ,recdlm ; /56/ end of line time today ?
- beq 10$ ; yes, dump the record out
- 5$: cmp bufp(r2),bufsiz(r2) ; is the buffer full ?
- blo 20$ ; no, store some more characters in it
- 10$: movb r0 ,r3 ; yes, save the input character r0
- calls putrec ,<buflst(r2),bufp(r2),r1> ; yes, dump the buffer please
- clr bufp(r2) ; pointer := 0
- tst r0 ; did it work ?
- bne 100$ ; no, die
- mov buflst(r2),r4 ; it worked. zero the buffer now
- mov bufsiz(r2),r0 ; get the buffer address and size
- 15$: clrb (r4)+ ; for i := 1 to bufsiz
- sob r0 ,15$ ; do buffer[i] := chr(0)
- movb r3 ,r0 ; ok, restore the old character
-
- 20$: cmp filtyp(r2),#binary ; once again, is this a binary file ?
- beq 30$ ; yes, ignore checks for <LF> and ^Z.
- cmp filtyp(r2),#terminal ; terminal file today ?
- beq 30$ ; yes, we want cr's and lf's
- cmpb r0 ,#lf ; we simply like to ignore line feeds
- beq 90$ ; bye
- cmpb r0 ,#'Z&37 ; control Z ?
- beq 90$ ; yes, ignore the control Z's please
- cmpb r0 ,#cr ; carraige return today ?
- beq 90$ ; yes, ignore it
- 30$: mov bufp(r2),r1 ; get the current buffer pointer
- add buflst(r2),r1 ; and point to a new home for the
- movb r0 ,@r1 ; the input character in r0
- inc bufp(r2) ; pointer := succ( pointer )
-
- 90$: clr r0 ; no errors
- 100$: unsave <r4,r3,r2,r1>
- return
-
- GLOBAL <recdlm> ; /56/
-
-
- .sbttl flush
-
-
- flush: mov @r5 ,r0 ; get the internal channel number
- asl r0 ; times 2 for indexing
- tst bufp(r0) ; anything in the buffer
- beq 100$ ; no
- tst mode(r0) ; writing today ?
- beq 100$ ; no
- calls putrec ,<buflst(r0),bufp(r0),@r5> ; yes, dump it
- return
- 100$: clr r0
- return
-
-
-
-
-
- .sbttl lookup do a filename lookup, wildcarding supported
- .enabl gbl
-
-
- ; L O O K U P
- ;
- ; input: @r5 arg count (DEC standard Fortran convention)
- ; 2(r5) address of input string
- ; @4(r5) flag word for initializing with a $PARSE
- ; 6(r5) address of output string
- ;
- ; output: r0 RMS error code
- ;
- ;
- ; clr index
- ;10$: calls lookup ,<#3,#inbuf,#index,#outbuf>
- ; tst r0
- ; bne 100$
- ; do something
- ; br 10$
-
-
-
-
- .mcall $parse ,$search,$store ,$fetch ,$compare
- .mcall fab$b ,fab$e ,nam$b ,nam$e
- .mcall $off $testbits ;RBD01
-
- .save
- .psect rmssup ,d
-
-
-
- fab: fab$b ; argument fab
- f$nam nam ; link to nam ;RBD01--
- f$lch 1 ; a dummy channel for the i/o op
- fab$e
-
- nam: nam$b ; nam definition
- n$esa expstr ; exp str address
- n$ess 64. ; exp str length
- n$rsa resstr ; res str address
- n$rss 64. ; res str length
- nam$e
-
- expstr: .blkb 64. ; context must be preserved here
- resstr: .blkb 64. ; a temp place for the result
-
- .restore
-
-
- .sbttl the real work of lookup
-
- .psect $pdata
- ; Make this <> 0 if you can't do CALFIP
- fu$dir::.word 0 ; style wildcarding on your non-standard
- ; RSTS system. Could cause side effects
- ; with remote decnet nodes.
- .psect $code
-
- lookup::tst rsx32 ; /56/ Ancient RSX today?
- beq 4$ ; /56/ No
- mov #ER$NMF ,r0 ; /56/ Yes, preset No More Files
- tst @4(r5) ; /56/ Second call?
- bne 3$ ; /56/ Yes, die
- STRCPY 6(r5) ,2(r5) ; /56/ No just return the passed string
- inc @4(r5) ; /56/ Note that we have been here
- clr r0 ; /56/ No errors
- 3$: return ; /56/ Exit
- ;
- 4$: save <r1,r2,r3,r4,r5> ; Save these please
- mov #fab ,r1 ; map the target fab ;RBD01--
- tst fu$def ; do we really need a default device?
- beq 5$ ; no
- $store #sydisk,DNA,r1 ; yes, please stuff the def device name
- $store #sylen ,DNS,r1 ; and the length of it also please
- 5$: strlen #defdir ; anything in the Kermit default dir?
- tst r0 ; if <> then use it
- beq 10$ ; nothing there to use. Let system do it
- $store #defdir ,DNA,r1 ; something was there, stuff it in
- $store r0 ,DNS,r1 ; and the length of the default
- 10$: mov r1 ,r0 ; save it for later
- mov #nam ,r3 ; map the target nam
- tst @4(r5) ; first time thru needs a parse
- bne 40$ ; not the first time
-
- clrb expstr ; clear the expanded name and
- clrb resstr ; the resultant string
- mov 2(r5) ,r4 ; point to the filename passed
- mov r4 ,r1 ; and save the pointer
- 20$: tstb (r1)+ ; and get the length of the name
- bne 20$ ; for an .asciz string
- sub r4 ,r1 ; compute the length of the string
- dec r1 ; which is off by one
- $store #lun.sr,lch,r0 ; channel number please
- $store r1,fns,r0 ; stuff the filename length
- $store r4,fna,r0 ; and the filename address
- $parse r0 ; parse the strings
- $fetch r4,sts,r0 ; get error codes
-
- cmp #ER$UIN,r4 ; Maybe a remote file spec? ;RBD01+
- bne 30$ ; (no)
- $testbits #<nb$wve!nb$wty!nb$wna!nb$wdi>,fnb,r3 ; Anything wild?
- bne 90$ ; (wild remote files no good)
- $testbits #nb$nod,fnb,r3 ; Remote file?
- beq 90$ ; (ER$UIN with no node???)
- $off #nb$wch,fnb,r3 ; Make succeeding $search's act nice
- $fetch r0,esl,r3 ; Pass back expanded string
- $fetch r2,esa,r3 ; and skip the $search.
- br 70$ ;RBD01-
-
- 30$: tst r4 ; < 0 ?
- bmi 90$ ; yes, error
-
- ; This added edit 2.12 by BDN for those RSTS systems that totally
- ; disallow directory lookups by modify the executive for non-priv
- ; users.
-
- 40$: tst fu$dir ; in case george w. @ purdue
- beq 50$ ; needs this due to a hacked up exec
- $testbits #<nb$wve!nb$wty!nb$wna!nb$wdi>,fnb,r3 ; Anything wild?
- bne 50$ ; yes, let the $search go on
- tst @4(r5) ; if no wildcarding and we have
- beq 45$ ; already been here then return
- mov #ER$NMF ,r4 ; no more files and exit
- br 90$ ; bye
- 45$: $fetch r0,esl,r3 ; no, skip the $search and get the
- $fetch r2,esa,r3 ; expanded string from $parse
- br 70$ ; and copy it over now
-
- ; End of option tp skip lookups for non-wildcarded filenames.
-
-
- 50$: $search r0 ; get a matching file
- $fetch r4,sts,r0 ; get error codes
- ; ;RBD01+
- ; The following shouldn't have been necessary, as I
- ; banged off the NB$WCH bit above. But ...
- ;
- cmp r4,#ER$UIN ; Remote file hacking?
- bne 60$ ; (no)
- mov #ER$FNF,r4 ; Yes, no "more" files
- br 90$ ; and exit
-
- 60$: tst r4 ; < 0 ? ;RBD01-
- bmi 90$ ; yes, error
- $fetch r0,rsl,r3 ; get the string length
- $fetch r2,rsa,r3 ; get the string address
-
- 70$: mov 6(r5) ,r1 ; where to return the string
- 80$: movb (r2)+ ,(r1)+ ; copy it over
- sob r0 ,80$ ; for however the long it is
- clrb @r1 ; insure .asciz please
- clr r0 ; no errors
- inc @4(r5) ; say we have at least one file
- br 100$ ; and exit
-
- 90$: mov r4 ,r0 ; error, return it please
- br 100$ ; exit
-
- 100$: unsave <r5,r4,r3,r2,r1>
- return
-
-
-
- .save
- .psect rendat ,rw,d,lcl,con,lcl
-
- .mcall $compare,$fetch ,$parse ,$search,$set ,$store
- .mcall fab$b ,nam$b ,$rename
-
- ; 24-Jan-86 14:01:48 Rename, Delete and GMCR code moved to overlay
-
-
- RNFAB1::FAB$B ; Old file name
- F$NAM RNNAM1 ; Link to RNNAM1 ;RBD01--
- F$LCH 1 ; Channel 1 (a dummy, filled in later)
- FAB$E
-
- RNNAM1::NAM$B ; NAM definition
- NAM$E
-
-
- RNFAB2::FAB$B ; New file name
- F$NAM RNNAM2 ; Link to RNNAM2 ;RBD01--
- F$LCH 1 ; a dummy channel
- FAB$E
-
- RNNAM2::NAM$B ; NAM definition
- NAM$E
-
-
- .restore
-
-
-
- .sbttl fparse parse filename and fill in with defaults
-
- .mcall $compar ,$fetch ,$off ,$parse ,$store
- .mcall tlog$s
-
- parfab = rnfab1
- parnam = rnnam1
-
-
- ; F P A R S E
- ;
- ; input: @r5 input filename, .asciz
- ; defdir the default directory name string to use
- ;
- ; output: 2(r5) expanded filename, .asciz, maximum length 63 bytes
- ; r0 error codes
-
-
- tlog:: save <r1,r2,r3> ; /46/ Save registers
- sub #200 ,sp ; /46/ Allocate a buffer
- mov sp ,r3 ; /46/ And a pointer to it please
- call getsys ; /46/ Is this RSTS/E ?
- cmpb r0 ,#SY$RSTS ; /46/ If so, don't try TLOG$S out
- beq 100$ ; /46/ Skip, must be RSTS/E
- strlen (r5) ; /46/ Get length of input string
- TLOG$S #0,ln$mk1,#0,(r5),r0,r3,#77,#tlogda,#tlogda+2
- cmpb @#$DSW,#IS.SUC ; /46/ Did we get a translation?
- bne 100$ ; /46/ No, exit this
- mov r3 ,r2 ; /46/ Setup to make it asciz
- add tlogda ,r3 ; /46/ Add the translated string length
- clrb (r3) ; /46/ in and insure it's .asciz
- strcpy (r5) ,r2 ; /46/ Copy new name over and exit
- 100$: add #200 ,sp ; /46/ Pop local buffer
- unsave <r3,r2,r1> ; /46/ Exit
- clr r0 ; /46/ No errors
- return ; /46/ Exit
-
- .save
- .psect $PDATA
- tlogda: .word 0,0 ; /46/ Returned data
- ln$mk1::.word 0
- .restore
-
-
- Fparse::tst rsx32 ; /56/ Old, old RSX?
- beq 1$ ; /56/ No
- STRCPY 2(r5) ,@r5 ; /56/ Yes, just copy the thing over
- clr r0 ; /56/ Success
- return ; /56/ Quick exit
- 1$: save <r1,r2,r3,r4> ; /46/ save registers we may overwrite
- mov @r5 ,r4 ; /46/ Assume input from source
- call getsys ; /46/ Is this RSTS/E ?
- cmpb r0 ,#SY$RSTS ; /46/ If so, don't try TLOG$S out
- beq 2$ ; /46/ Skip, must be RSTS/E
- mov 2(r5) ,r3 ; /46/ Address of a buffer to use
- strlen r4 ; /46/ Get length of input string
- TLOG$S #0,ln$mk1,#0,r4,r0,r3,#77,#tlogda,#tlogda+2
- cmpb @#$DSW,#IS.SUC ; /46/ Did we get a translation?
- bne 2$ ; /46/ No, exit this
- mov r3 ,r4 ; /46/ We did, set a new source address
- add tlogda ,r3 ; /46/ Add the translated string length
- clrb (r3) ; /46/ in and insure it's .asciz
- 2$: mov #parfab ,r1 ; point to the fab we use ;RBD01--
- $store #0,DNS,r1 ; /42/ PLEASE clear this OUT!
- tst fu$def ; do we need a defualt device string?
- beq 3$ ; no
- $store #sydisk,DNA,r1 ; yes, please put it where we need it
- $store #sylen ,DNS,r1 ; also, the length also
- 3$: strlen #defdir ; get the default directory spec
- tst r0 ; was anything there ?
- beq 4$ ; no
- $store #defdir,DNA,r1 ; yes, stuff that in for the default
- $store r0 ,DNS,r1 ; name string, and stuff the length.
- 4$: $store #lun.sr,LCH,r1 ; a channel number to use for $PARSE
- $off #fb$fid,FOP,r1 ; we want an implicit $SEARCH
- mov #parnam ,r2 ; also point to the NAME block
- sub #100 ,sp ; allocate result name string
- $store sp ,RSA,r2 ; set up the pointer to name string
- $store #100,RSS,r2 ; and set the size of the string
- sub #100 ,sp ; allocate result expanded name string
- $store sp ,ESA,r2 ; set up the pointer to expanded name
- $store #100,ESS,r2 ; and set the size of the string
- $store #ER$FNM ,STS,r1 ; preset a bad filename error
- strlen r4 ; /46/ get the length of the filename
- tst r0 ; anything left at all ?
- beq 90$ ; no, fake a bad filename please
- $store r0,FNS,r1 ; stuff the filename size in please
- $store r4,FNA,r1 ; /46/ stuff the filename address
- $parse r1 ; try to parse the filename now
-
- $compar #ER$UIN,sts,r1 ; Maybe a remote file spec? ;RBD01+
- bne 5$ ; (no)
- $testb #<nb$wve!nb$wty!nb$wna!nb$wdi>,fnb,r2 ; Anything wild?
- bne 90$ ; (wild remote files no good)
- $testb #nb$nod,fnb,r2 ; Remote file?
- beq 90$ ; (ER$UIN with no node???)
- $off #nb$wch,fnb,r2 ; Make succeeding $search's act nice
- br 7$ ; Go ahead with it ;RBD01-
-
- 5$: $compar #0 ,STS,r1 ; did the parse of the name work ?
- blt 90$ ; no, exit and return STS in r0
-
- 7$: mov 2(r5) ,r1 ; where we will copy the name to
- movb o$esl(r2),r0 ; the length of the new name
- beq 30$ ; can't happen unless you fubar
- cmp r0 ,#77 ; truncate names that are too long
- blos 10$ ; it's ok
- mov #77 ,r0 ; too long, please set it to 63 (10)
- 10$: mov o$esa(r2),r2 ; where the name is coming from
- 20$: movb (r2)+ ,(r1)+ ; copy a byte at a time please
- sob r0 ,20$ ; next please
- 30$: clrb @r1 ; insure .asciz please
- clr r0 ; no errors please
- br 100$ ; bye
-
- 90$: $fetch r0,STS,r1 ; error from parse, return in r0
- 100$: add #200 ,sp ; pop local nameblock buffers
- 110$: unsave <r4,r3,r2,r1> ; /46/ pop registers
- return ; bye
-
-
- global <defdir>
- GLOBAL <RSX32> ; /56/
-
-
- ; F I X W I L D
- ;
- ; FIXWILD will replace % with ? for RSTS/E
- ;
- ; input: @r5 Address of string to process
-
-
- fixwil::nop ; in case we want to patch to 207
- save <r2> ; save a register we use here
- calls getsys ; is this RSTS ?
- cmpb r0 ,#sy$rsts ;
- bne 100$ ; no
- mov @r5 ,r2 ; get the string address
- 10$: tstb @r2 ; done with the filename yet ?
- beq 100$ ; yes, exit
- cmpb @r2 ,#'% ; check for a % character
- bne 20$ ; no
- movb #'? ,@r2 ; yes, replace with question mark
- 20$: inc r2 ; next please
- br 10$ ; back again
- 100$: unsave <r2> ; pop r2
- clr r0 ; no errors
- return ; bye
-
-
-
- iswild::save <r1,r2> ; save a register we may use
- mov #parfab,r2 ; get a fab to use for this
- tst fu$def ; do we need a defualt device string?
- beq 5$ ; no
- $store #sydisk,DNA,r2 ; yes, please put it where we need it
- $store #sylen ,DNS,r2 ; also, the length also
- 5$: strlen #defdir ; get the default directory spec
- tst r0 ; was anything there ?
- beq 10$ ; no
- $store #defdir,DNA,r2 ; yes, stuff that in for the default
- $store r0 ,DNS,r2 ; name string, and stuff the length.
- 10$: $store @r5,FNA,r2 ; filename address
- strlen @r5 ; length
- $store r0,FNS,r2 ; into the FAB please
- $fetch r1,NAM,r2 ; get NAM block address
- clr O$ESA(r1) ; no expanded string address
- clr O$RSA(r1) ; no resultant string address
- clrb O$ESS(r1) ; no length fields either
- clrb O$RSS(r1) ; no length fields either
- $parse r2 ; parse the filename
- $fetch r0,STS,r2 ; get the status
- bmi 90$ ; exit on error please
- $testbi #NB$WVE!NB$WTY!NB$WNA!NB$WDI,FNB,r1 ; any wildcarding today ?
- beq 90$ ; no
- mov #1 ,r0 ; yes, return(true)
- br 100$ ; exit
- 90$: clr r0
- 100$: unsave <r2,r1> ; pop reg and exit
- return ; exit
-
-
-
-
-
-
-
-
- .sbttl return current task size and return exec
-
- .mcall gtsk$s ,gtim$s
-
-
-
- second::save <r2,r3> ; /43/ Get seconds past midnight
- sub #40 ,sp ; /43/ Used for reporting transfer
- mov sp ,r2 ; /43/ statistics
- gtim$s r2 ; /43/ One should really get the time
- mov g.timi(r2),r3 ; /43/ in the 64 bit klunk format to
- mul #60. ,r3 ; /43/ avoid 24 hour rollover, but
- add g.tisc(r2),r3 ; /43/ I really think this is
- mov g.tihr(r2),r0 ; /43/ sufficient
- clr r1 ; /43/ multiply hour of day by 3600
- mul #60.*60.,r0 ; /43/ which has to be 32 bits in
- add r3 ,r1 ; /43/ size, then add in minutes*60
- adc r0 ; /43/ + seconds.
- add #40 ,sp ; /43/ Pop buffer and exit
- unsave <r3,r2> ; /43/ Pop registers
- return ; /43/ Bye
-
- ; G E T S Y S
- ;
- ; output: r0 operating system
- ;
- ; sy$11m (1) for rsx11m
- ; sy$ias (3) for ias
- ; sy$rsts (4) for rsts
- ; sy$mpl (6) for m+
- ; sy$rt (7) for rt11 ????
-
-
- getsys::sub #40 ,sp ; use the stack for a buffer
- mov sp ,r0 ; and point to it please
- gtsk$s r0 ; simple
- mov g.tssy(r0),r0 ; return exec
- add #40 ,sp ; pop buffer and exit
- return ; bye
-
-
-
- .sbttl gsa get space for i/o buffers
-
-
- ; Modified from sample GSA from RMS v2 distribution
- ; by Brian Nelson 05-Jan-84 10:22:06
- ;
- ;
- ; Interface:
- ; Request space:
- ; R0 -> RMS/user Pool list head (maintained by RL/CQB)
- ; R1 := Amount of space requested (bytes)
- ; R2 := 0 (differentiates between request and release)
- ;
- ; Release space:
- ; R0 -> RMS Pool list head (maintained by RL/CQB)
- ; R1 := Amount of space to be released (bytes)
- ; R2 -> Base address (for release)
- ;
- ;
- ; Returns:
- ; C-Bit "set" if an error has occurred (failure)
- ; C-Bit "clear" if no error has occurred (success)
- ;
-
-
- .Mcall Extk$S
-
-
- .Sbttl Control block definitions
-
- .Psect GSA$$D,RW,D
-
- ;
- ; GSA internal data:
- ;
- ; GSABAS - Base address for the next memory allocation.
- ; Initially set to zero, it will be assigned
- ; the first address outside of the task's
- ; current address limits.
- ; GSAMIN - Decimal value reflecting the minimum size
- ; (in bytes) to extend the task in order to
- ; provide space to the pool.
- ; GSAREQ - Requested pool block number. If a request
- ; for the 'GSAMIN' fails, then the original
- ; allocation size will be attempted. If that
- ; fails, then there is no more memory left.
- ;
-
- GSABAS:: ; GSA base address
- .Word 000000 ; (for next allocation)
- GSAMIN:: ; Minimum allocation
- .Word 512./64. ; (in 32-word blocks)
- GSAREQ:: ; Size of this request
- .Word 000000 ; (if 'GSAMIN' extends fail)
-
-
-
- .Sbttl GSA Initialization code
-
- .Psect GSA$$I,RO,I
-
-
- .mcall extk$s ,gtsk$s
-
- GSAINI:
- Mov R0,-(SP) ; R0-2 will be used to
- Mov R1,-(SP) ; communicate with $INIDM
- Mov R2,-(SP) ; NOTE: $INIDM uses EXTSK.
- mov r0 ,-(sp) ; save r0
- sub #40 ,sp ; check for 512 boundary
- mov sp ,r0 ; get the current task size and see
- gtsk$s r0 ; if we are at a boundary. if so, then
- mov g.tsts(r0),r0 ; extend a little bit to get INIDM to
- add #40 ,sp ; behave itself
- bic #^c777 ,r0 ; strip all the high crap
- cmp r0 ,#776 ; should we extend a little bit?
- blo 10$ ; no
- extk$s #1 ; yes, get 64 more bytes please
- 10$: mov (sp)+ ,r0 ; restore r0
-
- Call $INIDM ; Initialize dynamic memory
- Mov R1,GSABAS ; Setup the "free" address
- Mov (SP)+,R2 ; Restore the registers
- Mov (SP)+,R1 ;
- Mov (SP)+,R0 ;
- Return ; And return to GSA
-
-
-
- .Sbttl GSA Mainline code
-
- .Psect GSA$$M,RO,I
-
- ;
- ; GSA Mainline
- ;
- ; Entry point is "GSA", with registers 0-2 loaded as
- ; described above.
- ;
-
- GSA::
- gsax:
-
- ;
- ; First, determine if dynamic memory has been initialized.
- ; GSABAS (initially set to zero) will be non-zero if $INIDM
- ; has been called and the memory list initialized. On RSX
- ; based systems it is possible to install tasks with an
- ; extension (/INCREMENT). $INIDM will detect this and setup
- ; the first memory entry in the pool list.
- ;
- ; A point to note: If the RSX task has been installed with
- ; the non-checkpointable (/-CP) flag, then EXTKs will not
- ; return success. If it is necessary to install the task
- ; non-checkpointable, then the task should be installed with
- ; and increment value.
- ;
-
- Tst GSABAS ; Dynamic memory initialized?
- Bne 10$ ; Yes if NE, proceed
- Call GSAINI ; Otherwise, initialize pool
- 10$: Tst R1 ; Real memory?
- Bne 20$ ; Yes if NE, then process it
- Return ; Otherwise return with success
-
-
- 20$: Tst R2 ; Address specified? (release)
- Beq 30$ ; No if EQ, then it's a request
- Jmp $RLCB ; Otherwise it's a release; do it
- 30$: Mov R0,-(SP) ; save pool list head
- Mov R1,-(SP) ; save size of request
- Mov R2,-(SP) ; save entry flag
- Call $RQCB ; Try the allocation
- Bcc 70$ ; CC signifies success
- Mov 2(SP),R1 ; Obtain the request size
- Add #63.,R1 ; Round the request
- Asr R1 ; to a 32-word boundary
- Asr R1 ; Then convert the value
- Asr R1 ; to the number of
- Asr R1 ; 32-word blocks.
- Asr R1
- Asr R1
- Mov R1,GSAREQ ; Save the real size
- Cmp R1,GSAMIN ; Smaller than minimum?
- Bhi 40$ ; No if HI, use it as is
- Mov GSAMIN,R1 ; Otherwise use GSAMIN
- 40$: Extk$S R1 ; Extend the task
- Bcc 60$ ; CC if successful
- Cmp R1,GSAREQ ; Is this request?
- Blos 50$ ; Yes if LOS, the end
- Mov GSAREQ,R1 ; Otherwise try to use
- Br 40$ ; the actual request
- 50$: Sec ; Mark failure
- Br 70$ ; And exit
-
- 60$: Mov 4(SP),R0 ; Setup the PLH
- Asl R1 ; Convert the real
- Asl R1 ; size to the actual
- Asl R1 ; 16-bit size that
- Asl R1 ; was allocated.
- Asl R1 ; The virtual address
- Asl R1 ; should be after the
- Mov GSABAS,R2 ; task (which is now
- Add R1,GSABAS ; part of the task)
- Call GSAX ; Call ourself to release
- Mov (SP)+,R2 ; Restore our registers
- Mov (SP)+,R1 ; to the initial state
- Mov (SP)+,R0 ; upon entry, and reenter
- Br GSAX ; as if it's a new request
-
- 70$: Inc (SP)+ ; These won't alter the
- Bit (SP)+,(SP)+ ; C-bit, so status remains
- Return ; unchanged upon return
-
-
-
- .sbttl Corrected version of $INIDM
-
- ; Re-do $INIDM to use the actual task top address, not
- ; that which was stored by TKB from the .LIMIT directive.
- ; This is required because we have already done a EXTK$S.
- ;
- ; 17-Feb-87 07:11:21 BDN edit 3.56
-
- .mcall GPRT$ ,GTSK$ ,DIR$ ,GTSK$S
- .Save
- .psect IMPURE ,d
-
- Limit: .Limit
- pdpb: GPRT$ tbuf
- tdpb: GTSK$ tbuf
-
- tbuf: .blkw 20
-
- .Restore
-
- .Psect PURE$I ,RO,I,LCL,REL,CON
-
- ; Inidm
- ;
- ; Input: r0 Address of free code pool listhead
- ; Output: r0 First address in task
- ; r1 Address following task
- ; r2 Size of core pool
-
- $Inidm::DIR$ #tdpb ; We already did an EXTK$S so
- mov tbuf+G.TSTS,r2 ; want to use the CURRENT topmem
- add #3 ,r2 ; Round up to next 4 byte boundary
- bic #3 ,r2 ; ...
- mov r2 ,@r0 ; Set base address of pool
- EXTK$S #1 ; Ask for just a little bit more
- DIR$ #pdpb ; Get partition parameters
- mov $DSW ,r0 ; Save starting address of partition
- DIR$ #tdpb ; Get task parameters
- mov r2 ,-(sp) ; Save starting address
- clr (r2)+ ; Clear out first word
- mov tbuf+G.TSTS,(r2) ; Set physical size of task
- sub r0 ,(sp) ; Compute apparent size of task
- mov r0 ,r1 ; Copy base address
- add (r2) ,r1 ; Next address after task
- sub (sp)+ ,(r2) ; Set size of free pool
- mov (r2) ,r2 ; Get size
- return ; And exit
-
- .end
-